<template>
  <div>
    <el-form
      ref="ruleFormRef"
      :model="ruleForm"
      :rules="rules"
      label-width="auto"
    >
      <el-form-item label="SPU名称" prop="name">
        <el-input v-model="ruleForm.name" />
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input v-model="ruleForm.description" type="textarea" />
      </el-form-item>
      <el-form-item label="SPU品牌" prop="tradeMarkId">
        <el-select
          v-model="ruleForm.tradeMarkId"
          placeholder="请选择品牌"
          style="width: 200px"
        >
          <el-option
            v-for="item in tradeMarkList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="SPU图标" prop="imageList">
        <el-upload
          v-model:file-list="fileList"
          action="http://localhost:9981/api/file/upload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img
            w-full
            :src="dialogImageUrl"
            alt="Preview Image"
            style="width: 100%; height: 100%"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="SPU销售属性" prop="attrNameList">
        <el-select
          v-model="selectedAttrName"
          :placeholder="`还有${unSelectedAttrName}个未使用`"
          style="width: 200px; margin-right: 10px"
          :disabled="unSelectedAttrName === 0"
        >
          <el-option
            v-for="item in attrNameList"
            :key="item.id"
            :label="item.name"
            :value="item.id + ':' + item.name"
          /> </el-select
        ><el-button
          type="primary"
          icon="Plus"
          @click="addAttrName"
          :disabled="!selectedAttrName"
          >添加SPU销售属性</el-button
        >
        <el-table :data="ruleForm.attrNameList" border style="margin: 10px 0">
          <el-table-column
            type="index"
            label="序号"
            :align="'center'"
            width="60"
          />
          <el-table-column
            prop="name"
            label="销售属性名称"
            :align="'center'"
            width="200"
          />
          <el-table-column
            prop="description"
            :align="'center'"
            label="销售属性值"
          >
            <template #="{ row }">
              <div>
                <el-tag
                  v-for="tag in row.valueList"
                  :key="tag.id"
                  closable
                  :disable-transitions="false"
                  @close="handleClose(row, tag)"
                  style="margin-right: 10px"
                >
                  {{ tag.name }}
                </el-tag>
                <el-input
                  v-if="row.inputVisible"
                  ref="InputRef"
                  v-model="inputValue"
                  size="small"
                  style="width: 160px"
                  @keyup.enter="handleInputConfirm(row)"
                  @blur="handleInputConfirm(row)"
                />
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(row)"
                >
                  +
                </el-button>
              </div></template
            >
          </el-table-column>
          <el-table-column :align="'center'" label="操作" width="200">
            <template #="scope"
              ><el-button
                type="danger"
                size="small"
                icon="Delete"
                @click="deleteAttrName(scope.row, scope.$index)"
              ></el-button
            ></template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(ruleFormRef)">
          确定
        </el-button>
        <el-button @click="cancelForm()">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts" name="Spu">
import type { SpuData } from '@/api/product/spu/type'
import type { TradeMarkData } from '@/api/product/treadmark/types'
import {
  ElMessage,
  type FormInstance,
  type InputInstance,
  type UploadProps,
} from 'element-plus'
import { computed, nextTick, reactive, ref } from 'vue'
import { reqTradeMarkList } from '@/api/product/treadmark/index'
import type { AttrNameData, AttrValueData } from '@/api/product/attr/types'
import { rqaAttrNameList } from '@/api/product/attr/index'
import type { FormRules } from 'element-plus/lib'
import { reqSaveSpu } from '@/api/product/spu/index'

// 表单数据
const ruleFormRef = ref()
const ruleForm = ref<SpuData>({} as any)
const rules = reactive<FormRules<SpuData>>({
  name: [
    { required: true, message: '名称不能为空', trigger: 'blur' },
    {
      min: 3,
      max: 8,
      message: '长度范围是3到8个汉字',
      trigger: 'blur',
    },
  ],
  description: [
    { required: true, message: '描述不能为空', trigger: 'blur' },
    {
      min: 3,
      max: 10,
      message: '长度范围是3到10个汉字',
      trigger: 'blur',
    },
  ],
  tradeMarkId: [{ required: true, message: '品牌不能为空', trigger: 'blur' }],
})
// 页面展示的品牌列表
const tradeMarkList = ref<TradeMarkData[]>([])
// 页面展示的图片列表
const fileList = ref<{ url: string; response?: any }[]>([])
// 暂存所有的销售属性列表
const allAttrNameList = ref<AttrNameData[]>([])
// 页面展示的销售属性列表
const attrNameList = computed(() => {
  const idSet = new Set(ruleForm.value.attrNameList?.map((item) => item.id))
  // filter返回的是一个新的数组
  return allAttrNameList.value.filter((item) => !idSet.has(item.id))
})
const emit = defineEmits(['submit', 'cancel'])
const initSpuForm = async (spuData: SpuData) => {
  // 深拷贝待编辑的数据
  ruleForm.value = JSON.parse(JSON.stringify(spuData))
  if (!ruleForm.value.attrNameList) {
    ruleForm.value.attrNameList = []
  }
  // 清除表单校验信息
  ruleFormRef.value?.clearValidate('name')
  ruleFormRef.value?.clearValidate('description')
  ruleFormRef.value?.clearValidate('tradeMarkId')
  // 查询展示其他表单初始化数据
  tradeMarkList.value = (await reqTradeMarkList(1, 1000)).data.list
  // 数据转换：字符串数组转对象数组
  fileList.value = spuData.imageList?.map((item) => ({ url: item }))
  // 销售属性列表
  allAttrNameList.value = (await rqaAttrNameList(spuData.attrId)).data || []
}
defineExpose({ initSpuForm })
// 销售图片列表相关
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {}
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile
) => {}
// 添加SPU销售属性
const selectedAttrName = ref('')
const addAttrName = () => {
  let [attrNameId, attrName] = selectedAttrName.value.split(':')
  const toAddAttrName = allAttrNameList.value.find(
    (item) => item.id === Number(attrNameId)
  )
  // toAddAttrName可能为空，! 表示 toAddAttrName 一定不为空
  ruleForm.value.attrNameList.push(toAddAttrName!)
  // 让select组件显示placeholder内容
  selectedAttrName.value = ''
}
// 响应式计算还有多个销售属性未添加
let unSelectedAttrName = computed<number>(() => {
  // 计算属性：在使用是就会执行一次
  const idSet = new Set(ruleForm.value.attrNameList?.map((item) => item.id))
  return attrNameList.value.filter((item) => !idSet.has(item.id)).length
})
const deleteAttrName = (row: AttrNameData, index: number) => {
  ruleForm.value.attrNameList.splice(index, 1)
}
// 销售属性值相关
const handleClose = (row: AttrNameData, tag: AttrValueData) => {
  row.valueList.splice(
    row.valueList.findIndex((item) => item.id === tag.id),
    1
  )
}
// 由于同时只能存在一个 InputRef ，所以此处用一个InputRef即可
const InputRef = ref<InputInstance>()
const inputValue = ref('')
const showInput = (row: AttrNameData) => {
  row.inputVisible = true
  nextTick(() => {
    InputRef.value!.focus()
  })
}
const handleInputConfirm = (row: AttrNameData) => {
  if (inputValue.value) {
    row.valueList.push({ id: Date.now(), name: inputValue.value })
  }
  row.inputVisible = false
  inputValue.value = ''
}
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      ruleForm.value.imageList = fileList.value?.map((item) => {
        if (item.response?.data) {
          return item.response?.data
        } else {
          return item.url
        }
      })
      let response = await reqSaveSpu(ruleForm.value)
      if (response.code === 200) {
        ElMessage.success(ruleForm.value.id ? '修改SPU成功' : '添加SPU成功')
        emit('submit')
      } else {
        ElMessage.error(ruleForm.value.id ? '添加SPU成功' : '添加品SPU成功')
      }
    } else {
      ElMessage.error('请按规范输入待提交信息！')
    }
  })
}
const cancelForm = () => {
  emit('cancel')
}
</script>

<style scoped></style>
